﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Xml;
using Fingerbrisk.DataSource.FluentDatasourceInteract;
using Moq;

namespace DocumentBuilder.Components
{
    public class Query
    {
        private readonly Mock<IQueryExpression> _expressionMock = null;
        private readonly DataSet _dummyDataSet = null;

        private IQueryExpression Expression
        {
            get { return _expressionMock.Object; }
        }

        private Query()
        {
            #region Dummy Dataset
            _dummyDataSet = new DataSet("Dummy");

            var table = new DataTable("Content");
            table.Columns.Add(new DataColumn("Id", typeof(Int32)));
            table.Columns.Add(new DataColumn("Title", typeof(String)));
            table.Columns.Add(new DataColumn("Description", typeof(String)));
            table.Columns.Add(new DataColumn("UserId", typeof(Int32)));

            var row = table.NewRow();
            row["Id"] = 1;
            row["Title"] = "Dynamic LINQ";
            row["Description"] = "Dynamic LINQ supports query written in string, which are compiled at runtime.";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 2;
            row["Title"] = "Fluent Interfaces";
            row["Description"] = "Fluent Interface are used a lot nowdays to make look program more like a sentence.";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 3;
            row["Title"] = "Mocking Framework";
            row["Description"] = "Mocking Framewoks allows you to create mocks for your unimplemented interfaces. One such awesome framework is MOQ (mo-quee)";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 4;
            row["Title"] = "BDD";
            row["Description"] = "Behavior Driven Development is an umbrella concept which includes lot of other terms as TDD or Feature Driven Development. Microsoft provides SpecFlow as the BDD framework";
            row["UserId"] = 2;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 2;
            row["Title"] = "Fluent Interfaces";
            row["Description"] = "Fluent Interface are used a lot nowdays to make look program more like a sentence.";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 3;
            row["Title"] = "Mocking Framework";
            row["Description"] = "Mocking Framewoks allows you to create mocks for your unimplemented interfaces. One such awesome framework is MOQ (mo-quee)";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 4;
            row["Title"] = "BDD";
            row["Description"] = "Behavior Driven Development is an umbrella concept which includes lot of other terms as TDD or Feature Driven Development. Microsoft provides SpecFlow as the BDD framework";
            row["UserId"] = 2;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 2;
            row["Title"] = "Fluent Interfaces";
            row["Description"] = "Fluent Interface are used a lot nowdays to make look program more like a sentence.";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 3;
            row["Title"] = "Mocking Framework";
            row["Description"] = "Mocking Framewoks allows you to create mocks for your unimplemented interfaces. One such awesome framework is MOQ (mo-quee)";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 4;
            row["Title"] = "BDD";
            row["Description"] = "Behavior Driven Development is an umbrella concept which includes lot of other terms as TDD or Feature Driven Development. Microsoft provides SpecFlow as the BDD framework";
            row["UserId"] = 2;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 2;
            row["Title"] = "Fluent Interfaces";
            row["Description"] = "Fluent Interface are used a lot nowdays to make look program more like a sentence.";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 3;
            row["Title"] = "Mocking Framework";
            row["Description"] = "Mocking Framewoks allows you to create mocks for your unimplemented interfaces. One such awesome framework is MOQ (mo-quee)";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 4;
            row["Title"] = "BDD";
            row["Description"] = "Behavior Driven Development is an umbrella concept which includes lot of other terms as TDD or Feature Driven Development. Microsoft provides SpecFlow as the BDD framework";
            row["UserId"] = 2;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 2;
            row["Title"] = "Fluent Interfaces";
            row["Description"] = "Fluent Interface are used a lot nowdays to make look program more like a sentence.";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 3;
            row["Title"] = "Mocking Framework";
            row["Description"] = "Mocking Framewoks allows you to create mocks for your unimplemented interfaces. One such awesome framework is MOQ (mo-quee)";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 4;
            row["Title"] = "BDD";
            row["Description"] = "Behavior Driven Development is an umbrella concept which includes lot of other terms as TDD or Feature Driven Development. Microsoft provides SpecFlow as the BDD framework";
            row["UserId"] = 2;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 2;
            row["Title"] = "Fluent Interfaces";
            row["Description"] = "Fluent Interface are used a lot nowdays to make look program more like a sentence.";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 3;
            row["Title"] = "Mocking Framework";
            row["Description"] = "Mocking Framewoks allows you to create mocks for your unimplemented interfaces. One such awesome framework is MOQ (mo-quee)";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 4;
            row["Title"] = "BDD";
            row["Description"] = "Behavior Driven Development is an umbrella concept which includes lot of other terms as TDD or Feature Driven Development. Microsoft provides SpecFlow as the BDD framework";
            row["UserId"] = 2;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 2;
            row["Title"] = "Fluent Interfaces";
            row["Description"] = "Fluent Interface are used a lot nowdays to make look program more like a sentence.";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 3;
            row["Title"] = "Mocking Framework";
            row["Description"] = "Mocking Framewoks allows you to create mocks for your unimplemented interfaces. One such awesome framework is MOQ (mo-quee)";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 4;
            row["Title"] = "BDD";
            row["Description"] = "Behavior Driven Development is an umbrella concept which includes lot of other terms as TDD or Feature Driven Development. Microsoft provides SpecFlow as the BDD framework";
            row["UserId"] = 2;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 2;
            row["Title"] = "Fluent Interfaces";
            row["Description"] = "Fluent Interface are used a lot nowdays to make look program more like a sentence.";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 3;
            row["Title"] = "Mocking Framework";
            row["Description"] = "Mocking Framewoks allows you to create mocks for your unimplemented interfaces. One such awesome framework is MOQ (mo-quee)";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 4;
            row["Title"] = "BDD";
            row["Description"] = "Behavior Driven Development is an umbrella concept which includes lot of other terms as TDD or Feature Driven Development. Microsoft provides SpecFlow as the BDD framework";
            row["UserId"] = 2;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 2;
            row["Title"] = "Fluent Interfaces";
            row["Description"] = "Fluent Interface are used a lot nowdays to make look program more like a sentence.";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 3;
            row["Title"] = "Mocking Framework";
            row["Description"] = "Mocking Framewoks allows you to create mocks for your unimplemented interfaces. One such awesome framework is MOQ (mo-quee)";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 4;
            row["Title"] = "BDD";
            row["Description"] = "Behavior Driven Development is an umbrella concept which includes lot of other terms as TDD or Feature Driven Development. Microsoft provides SpecFlow as the BDD framework";
            row["UserId"] = 2;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 2;
            row["Title"] = "Fluent Interfaces";
            row["Description"] = "Fluent Interface are used a lot nowdays to make look program more like a sentence.";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 3;
            row["Title"] = "Mocking Framework";
            row["Description"] = "Mocking Framewoks allows you to create mocks for your unimplemented interfaces. One such awesome framework is MOQ (mo-quee)";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 4;
            row["Title"] = "BDD";
            row["Description"] = "Behavior Driven Development is an umbrella concept which includes lot of other terms as TDD or Feature Driven Development. Microsoft provides SpecFlow as the BDD framework";
            row["UserId"] = 2;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 2;
            row["Title"] = "Fluent Interfaces";
            row["Description"] = "Fluent Interface are used a lot nowdays to make look program more like a sentence.";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 3;
            row["Title"] = "Mocking Framework";
            row["Description"] = "Mocking Framewoks allows you to create mocks for your unimplemented interfaces. One such awesome framework is MOQ (mo-quee)";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 4;
            row["Title"] = "BDD";
            row["Description"] = "Behavior Driven Development is an umbrella concept which includes lot of other terms as TDD or Feature Driven Development. Microsoft provides SpecFlow as the BDD framework";
            row["UserId"] = 2;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 2;
            row["Title"] = "Fluent Interfaces";
            row["Description"] = "Fluent Interface are used a lot nowdays to make look program more like a sentence.";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 3;
            row["Title"] = "Mocking Framework";
            row["Description"] = "Mocking Framewoks allows you to create mocks for your unimplemented interfaces. One such awesome framework is MOQ (mo-quee)";
            row["UserId"] = 1;
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 4;
            row["Title"] = "BDD";
            row["Description"] = "Behavior Driven Development is an umbrella concept which includes lot of other terms as TDD or Feature Driven Development. Microsoft provides SpecFlow as the BDD framework";
            row["UserId"] = 2;
            table.Rows.Add(row);

            _dummyDataSet.Tables.Add(table);


            table = new DataTable("Users");
            table.Columns.Add(new DataColumn("Id", typeof(Int32)));
            table.Columns.Add(new DataColumn("FirstName", typeof(String)));
            table.Columns.Add(new DataColumn("LastName", typeof(String)));

            row = table.NewRow();
            row["Id"] = 1;
            row["FirstName"] = "Jack";
            row["LastName"] = "Daniel";
            table.Rows.Add(row);

            row = table.NewRow();
            row["Id"] = 2;
            row["FirstName"] = "Jason";
            row["LastName"] = "Bourne";
            table.Rows.Add(row);

            _dummyDataSet.Tables.Add(table);
            #endregion

            _expressionMock = new Mock<IQueryExpression>();
            _expressionMock.Setup(e => e.Execute()).Returns(_dummyDataSet);
        }

        public String Id { get; private set; }

        /// <summary>
        /// Fills the data from query to the ViewObject
        /// </summary>
        /// <param name="viewObject">Type of viewObject to be filled</param>
        /// <returns>List of viewobjects</returns>
        public List<ViewObject> Fill(ViewObject viewObject)
        {
            var dataSet = Expression.Execute();
            var result = new List<ViewObject>();

            foreach (DataRow row in dataSet.Tables[0].Rows)
            {
                var view = new ViewObject(viewObject.Name);

                foreach(var key in viewObject.Fields.Keys)
                {
                    var field = viewObject.Fields[key];

                    if (dataSet.Tables[0].Columns.Contains(field.DbKey))
                    {
                        view.Fields.Add(field.Name, new Field(field.Name, field.DbKey, field.Format){ Value = row[field.DbKey].ToString() });
                    }
                    else
                    {
                        view.Fields.Add(field.Name, new Field(field.Name, field.DbKey, field.Format));
                    }
                }

                result.Add(view);
            }

            return result;
        }

        /// <summary>
        /// Execute and returns the scalar value
        /// </summary>
        /// <returns>Scalar object value</returns>
        public object Execute()
        {
            return new object();
        }

        public static Query Create(Document context, XmlNode view)
        {
            var query = new Query();
            query.Id = view.Attributes["id"].Value;

            return query;
        }
    }
}